package xxl.robotlegs.extensions.directcommandmap.impl 
{
	import xxl.robotlegs.extensions.commandcenter.api.ICommandExecutor;
	import xxl.robotlegs.extensions.commandcenter.api.ICommandMappingList;
	import xxl.robotlegs.extensions.commandcenter.impl.CommandExecutor;
	import xxl.robotlegs.extensions.commandcenter.impl.CommandMappingList;
	import xxl.robotlegs.extensions.commandcenter.impl.CommandPayload;
	import xxl.robotlegs.extensions.commandcenter.impl.NullCommandTrigger;
	import xxl.robotlegs.extensions.directcommandmap.api.IDirectCommandConfigurator;
	import xxl.robotlegs.extensions.directcommandmap.api.IDirectCommandMap;
	import xxl.robotlegs.extensions.directcommandmap.api.IDirectCommandMapper;
	import xxl.robotlegs.framework.api.IContext;
	import xxl.robotlegs.framework.api.IInjector;
	/**
	 * ...
	 * @author XXL
	 */
	public class DirectCommandMap implements IDirectCommandMap
	{
		private const _mappingProcessors:Array = [];
		private var _context:IContext;
		private var _mappings:ICommandMappingList;
		private var _executor:ICommandExecutor;
		
		public function DirectCommandMap(context:IContext) 
		{
			_context = context;
			const sandboxedInjector:IInjector = context.injector.createChild();
			sandboxedInjector.map(IDirectCommandMap).toValue(this);
			_mappings = new CommandMappingList(new NullCommandTrigger(), _mappingProcessors, context.getLogger(this));
			_executor = new CommandExecutor(sandboxedInjector, _mappings.removeMapping);
		}
		
		/* INTERFACE xxl.robotlegs.extensions.directcommandmap.api.IDirectCommandMapper */
		
		public function map(commandClass:Class):IDirectCommandConfigurator 
		{
			return new DirectCommandMapper(_executor, _mappings, commandClass);
		}
		
		public function execute(payload:CommandPayload = null):void 
		{
			_executor.executeCommands(_mappings.getList(), payload);
		}
		
		/* INTERFACE xxl.robotlegs.extensions.directcommandmap.api.IDirectCommandMap */
		
		public function detain(command:Object):void 
		{
			_context.detain(command);
		}
		
		public function release(command:Object):void 
		{
			_context.release(command);
		}
		
		public function addMappingProcessor(handler:Function):IDirectCommandMap 
		{
			if (_mappingProcessors.indexOf(handler) < 0)
			{
				_mappingProcessors.push(handler);
			}
			return this;
		}
		
	}

}